package com.iefgames.cs.pople;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mortbay.util.ajax.Continuation;
import org.mortbay.util.ajax.ContinuationSupport;

import com.iefgames.cs.comet.IComet;
import com.iefgames.cs.exception.DisconnectionException;
import com.iefgames.cs.framework.utils.JsonUtil;
import com.iefgames.cs.manager.CometManager;
import com.iefgames.cs.shout.AbstractShout;

public abstract class Pople implements IComet {
	private Log logger = LogFactory.getLog(Pople.class);
	
	private String uuid = null;
	
	private Continuation continuation = null;
	
	private State state = null;

	private long sleepTime = 0l;
	
	private long cometTime = 0l;		//每次comet的时间

	public abstract boolean isCs();
	
	private Vector<AbstractShout> Msgs = new Vector<AbstractShout>();

	@SuppressWarnings("unchecked")
	public void fire(HttpServletRequest request, HttpServletResponse response) {
		Continuation continuation = ContinuationSupport.getContinuation(request, null);
		
		if (Msgs.isEmpty()) {
			heartbear(request, response);
		} else {
			PrintWriter writer = null;
			try {
				writer = response.getWriter();
				writer.append(JsonUtil.toJs(Msgs));
				writer.close();
			} catch (IOException e) {}
				
			logger.debug(JsonUtil.toJs(Msgs));
			
			if (writer.checkError()) {
				throw new DisconnectionException(request, response);
			}
			
			Msgs.clear();
			setState(State.Comeback);
			startSleep();
			
			return;
		}
		
		if (continuation.isPending()) {
			continuation.reset();
		}
		
		continuation.suspend(3 * 1000);
//		continuation.suspend(CometManager.MaxSleepTime);
	}
	
	private void heartbear(HttpServletRequest request, HttpServletResponse response) {
		PrintWriter writer = null;
		try {
			writer = response.getWriter();
			writer.append(' ');
		} catch (IOException e) { }
		
		if (writer.checkError()) {
			throw new DisconnectionException(request, response);
		}
	}
	
	protected void setNoCacheHeader(HttpServletResponse response) {
	  response.setContentType("text/html; charset=utf-8");
	  // Set to expire far in the past.
	  response.setHeader("Expires", "Sat, 6 May 1995 12:00:00 GMT");
	
	  // Set standard HTTP/1.1 no-cache headers.
	  response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
	
	  // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
	  response.addHeader("Cache-Control", "post-check=0, pre-check=0");
	
	  // Set standard HTTP/1.0 no-cache header.
	  response.setHeader("Pragma", "no-cache");
	}
	
	public String getUuid() {
		return uuid;
	}

	protected void setUuid(String uuid) {
		this.uuid = uuid;
	}

	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}

	public Continuation getContinuation() {
		return continuation;
	}

	public void setContinuation(Continuation continuation) {
		this.continuation = continuation;
	}
	
	public long getTime() {
		return sleepTime;
	}
	
	public void startSleep() {
		this.sleepTime = System.currentTimeMillis();
	}
	
	public boolean isOnline() {
		return getState() == State.Online || getState() == State.Comeback && System.currentTimeMillis() - getTime() < CometManager.MaxSleepTime;
	}
	
	public boolean isOffline() {
		return !isOnline();
	}
	
	
	public long getCometTime() {
		return cometTime;
	}

	public void setCometTime(long cometTime) {
		this.cometTime = cometTime;
	}
	
	public Vector<AbstractShout> getMsgs() {
		return Msgs;
	}

	public void addMsg(AbstractShout msg) {
		Msgs.add(msg);
	}
	
}
